package com.changanw.middleware.dynamic.thread.pool.trigger;

import com.alibaba.fastjson.JSON;

import com.changanw.dynamic.thread.pool.sdk.domain.model.ThreadPoolConfigEntity;
import com.changanw.middleware.dynamic.thread.pool.types.Response;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RList;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author changanw
 * @description
 * @date 2024/5/20 14:17
 */
@Slf4j
@RestController()
@CrossOrigin("*")
@RequestMapping("/api/v1/dynamic/thread/pool/")
public class DynamicThreadPoolController {
  @Resource
  public RedissonClient redissonClient;

  /**
   * 查询线程池数据信息
   * curl --request GET \
   * --url 'http://localhost:8089/api/v1/dynamic/thread/pool/query_thread_pool_list'
   * @return
   */
  @RequestMapping(value = "query_thread_pool_list", method = RequestMethod.GET)
  public Response<List<ThreadPoolConfigEntity>> queryThreadPoolList() {
    try {
      RList<ThreadPoolConfigEntity> cacheList = redissonClient.getList("THREAD_POOL_CONFIG_LIST_KEY");
      return Response.<List<ThreadPoolConfigEntity>>builder()
              .code(Response.Code.SUCCESS.getCode())
              .info(Response.Code.SUCCESS.getInfo())
              .data(cacheList.readAll())
              .build();
    } catch (Exception e) {
      log.error("查询线程池数据异常", e);
      return Response.<List<ThreadPoolConfigEntity>>builder()
              .code(Response.Code.UN_ERROR.getCode())
              .info(Response.Code.UN_ERROR.getInfo())
              .build();
    }
  }
  /**
   * 查询线程池配置
   * curl --request GET \
   * --url 'http://localhost:8089/api/v1/dynamic/thread/pool/query_thread_pool_config?appName=dynamic-thread-pool-test-app&threadPoolName=threadPoolExecutor'
   */
  @RequestMapping(value = "query_thread_pool_config", method = RequestMethod.GET)
  public Response<ThreadPoolConfigEntity> queryThreadPoolConfig(@RequestParam String appName, @RequestParam String threadPoolName) {
    try {
      String cacheKey = "THREAD_POOL_CONFIG_PARAMETER_LIST_KEY" + "_" + appName + "_" + threadPoolName;
      ThreadPoolConfigEntity threadPoolConfigEntity = redissonClient.<ThreadPoolConfigEntity>getBucket(cacheKey).get();
      return Response.<ThreadPoolConfigEntity>builder()
              .code(Response.Code.SUCCESS.getCode())
              .info(Response.Code.SUCCESS.getInfo())
              .data(threadPoolConfigEntity)
              .build();
    } catch (Exception e) {
      log.error("查询线程池配置异常", e);
      return Response.<ThreadPoolConfigEntity>builder()
              .code(Response.Code.UN_ERROR.getCode())
              .info(Response.Code.UN_ERROR.getInfo())
              .build();
    }
  }

  /**
   * 修改线程池配置
   * curl --request POST \
   * --url http://localhost:8089/api/v1/dynamic/thread/pool/update_thread_pool_config \
   * --header 'content-type: application/json' \
   * --data '{
   * "appName":"dynamic-thread-pool-test-app",
   * "threadPoolName": "threadPoolExecutor",
   * "corePoolSize": 1,
   * "maximumPoolSize": 10
   * }'
   */
  @RequestMapping(value = "update_thread_pool_config", method = RequestMethod.POST)
  public Response<Boolean> updateThreadPoolConfig(@RequestBody ThreadPoolConfigEntity request) {
    try {
      int corePoolSize = request.getCorePoolSize();
      int maximumPoolSize = request.getMaximumPoolSize();
      if (maximumPoolSize < corePoolSize){
        log.info("修改线程池错误 {} {} {},最大线程数小于核心线程数", request.getAppName(), request.getThreadPoolName(), JSON.toJSONString(request));
        return Response.<Boolean>builder()
                .code(Response.Code.UN_ERROR.getCode())
                .info(Response.Code.UN_ERROR.getInfo())
                .data(false)
                .build();
      }
      log.info("修改线程池配置开始 {} {} {}", request.getAppName(), request.getThreadPoolName(), JSON.toJSONString(request));
      RTopic topic = redissonClient.getTopic("DYNAMIC_THREAD_POOL_REDIS_TOPIC" + "_" + request.getAppName());
      topic.publish(request);
      log.info("修改线程池配置完成 {} {}", request.getAppName(), request.getThreadPoolName());
      return Response.<Boolean>builder()
              .code(Response.Code.SUCCESS.getCode())
              .info(Response.Code.SUCCESS.getInfo())
              .data(true)
              .build();
    } catch (Exception e) {
      log.error("修改线程池配置异常 {}", JSON.toJSONString(request), e);
      return Response.<Boolean>builder()
              .code(Response.Code.UN_ERROR.getCode())
              .info(Response.Code.UN_ERROR.getInfo())
              .data(false)
              .build();
    }
  }
}
